About unsupported resource level permissions of the Amazon EC2 API
Many Amazon EC2 APIs can control access permission with "Resource-level permissions". However, some actions do not support "Resource-level permissions". Furthermore, these actions tend to be overlooked.
In this post, we will introduce the error contents and workarounds for creating IAM policies that specify actions not supported by "Resource-level permissions".
Example IAM Policy
For example, you create an IAM policy under the following conditions.
- Resources:specific EC2 instance
- Actions:stop / start / reboot / CreateImage for EC2 instance
- Effect: Allow
IAM policy where the error occurred
Suppose you create the following IAM policy using "Policy Generator":
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt000", "Effect": "Allow", "Action": [ "ec2:Describe*", "ec2:CreateImage", "ec2:CreateSnapshot", "ec2:RebootInstances", "ec2:StartInstances", "ec2:StopInstances" ], "Resource": [ "arn:aws:ec2:us-west-2:<aws account id>:instance/<instance id>" ] } ] }
At first glance, there seems to be no problem in the above policy. However, the policy contains actions that do not support Resource-level Permissions. If you execute this action, you will see an error message: "You are not authorized to perform this operation."
$ aws ec2 create-image --no-reboot --name "backup-${today}-${instance-id}" --instance-id ${instance-id} An error occurred (UnauthorizedOperation) when calling the CreateImage operation: You are not authorized to perform this operation.
Thus the IAM policy needs to be adjusted to account for actions that do not support Resource-level Permissions.
Corrected IAM policy
The statement is separated into actions that support Resource-Level Permissions and actions that don't support Resource-Level Permissions:
{ "Version": "2012-10-17", "Statement": [ { "Sid": "Stmt000", "Effect": "Allow", "Action": [ "ec2:CreateImage", "ec2:CreateSnapshot", "ec2:Describe*" ], "Resource": [ "*" ] }, { "Sid": "Stmt001", "Effect": "Allow", "Action": [ "ec2:RebootInstances", "ec2:StartInstances", "ec2:StopInstances" ], "Resource": [ "arn:aws:ec2:us-west-2:<aws account id>:instance/<instance id>" ] } ] }
For easy reference, we list some supported and unsupported Resource-Level Permissions.
Supported Resource-Level Permissions
- RebootInstances
- StartInstances
- StopInstances
The above actions support resource-level permissions. Therefore, these actions are controlled using "Resource element".
{ "Sid": "Stmt001", "Effect": "Allow", "Action": [ "ec2:RebootInstances", "ec2:StartInstances", "ec2:StopInstances" ], "Resource": [ "arn:aws:ec2:us-west-2:<aws account id>:instance/<instance id>" ] }
Unsupported Resource-Level Permissions
- CreateSnapshot
- CreateImage
- Describe*
The above actions do not support resource-level permissions. Therefore, you must grant a * wildcard for "Resource element".
{ "Sid": "Stmt000", "Effect": "Allow", "Action": [ "ec2:CreateImage", "ec2:CreateSnapshot", "ec2:Describe*" ], "Resource": [ "*" ] },
List of Unsupported Resource-Level Permissions
The following Amazon EC2 API actions do not support resource-level permissions at this time. Therefore, a * wildcard must be used for "Resource Element" as shown in the Corrected IAM policy.
AcceptReservedInstancesExchangeQuote AllocateAddress AllocateHosts AssignIpv6Addresses AssignPrivateIpAddresses AssociateAddress AssociateDhcpOptions AssociateRouteTable AssociateSubnetCidrBlock AssociateVpcCidrblock AttachInternetGateway AttachNetworkInterface AttachVpnGateway BundleInstance CancelBundleTask CancelConversionTask CancelExportTask CancelImportTask CancelReservedInstancesListing CancelSpotFleetRequests CancelSpotInstanceRequests ConfirmProductInstance CopyImage CopySnapshot CreateCustomerGateway CreateDefaultVpc CreateDhcpOptions CreateEgressOnlyInternetGateway CreateFlowLogs CreateFpgaImage CreateImage CreateInstanceExportTask CreateInternetGateway CreateKeyPair CreateNatGateway CreateNetworkAcl CreateNetworkAclEntry CreateNetworkInterface CreateNetworkInterfacePermission CreatePlacementGroup CreateReservedInstancesListing CreateRoute CreateRouteTable CreateSecurityGroup CreateSnapshot CreateSpotDatafeedSubscription CreateSubnet CreateVpc CreateVpcEndpoint CreateVpnConnection CreateVpnConnectionRoute CreateVpnGateway DeleteEgressOnlyInternetGateway DeleteFlowLogs DeleteKeyPair DeleteNatGateways DeleteNetworkInterface DeleteNetworkInterfacePermission DeletePlacementGroup DeleteSnapshot DeleteSpotDatafeedSubscription DeleteSubnet DeleteVpc DeleteVpcEndpoints DeleteVpnConnection DeleteVpnConnectionRoute DeleteVpnGateway DeregisterImage DescribeAccountAttributes DescribeAddresses DescribeAvailabilityZones DescribeBundleTasks DescribeClassicLinkInstances DescribeConversionTasks DescribeCustomerGateways DescribeDhcpOptions DescribeEgressOnlyInternetGateways DescribeElasticGpus DescribeExportTasks DescribeFlowLogs DescribeFpgaImages DescribeHosts DescribeIamInstanceProfileAssociations DescribeIdentityIdFormat DescribeIdFormat DescribeImageAttribute DescribeImages DescribeImportImageTasks DescribeImportSnapshotTasks DescribeInstanceAttribute DescribeInstances DescribeInstanceStatus DescribeInternetGateways DescribeKeyPairs DescribeMovingAddresses DescribeNatGateways DescribeNetworkAcls DescribeNetworkInterfaceAttribute DescribeNetworkInterfacePermissions DescribeNetworkInterfaces DescribePlacementGroups DescribePrefixLists DescribeRegions DescribeReservedInstances DescribeReservedInstancesListings DescribeReservedInstancesModifications DescribeReservedInstancesOfferings DescribeRouteTables DescribeScheduledInstanceAvailability DescribeScheduledInstances DescribeSecurityGroupReferences DescribeSecurityGroups DescribeSnapshotAttribute DescribeSnapshots DescribeSpotDatafeedSubscription DescribeSpotFleetInstances DescribeSpotFleetRequestHistory DescribeSpotFleetRequests DescribeSpotInstanceRequests DescribeSpotPriceHistory DescribeStaleSecurityGroups DescribeSubnets DescribeTags DescribeVolumeAttribute DescribeVolumes DescribeVolumesModifications DescribeVolumeStatus DescribeVpcAttribute DescribeVpcClassicLink DescribeVpcClassicLinkDnsSupport DescribeVpcEndpoints DescribeVpcEndpointServices DescribeVpcPeeringConnections DescribeVpcs DescribeVpnConnections DescribeVpnGateways DetachInternetGateway DetachNetworkInterface DetachVpnGateway DisableVgwRoutePropagation DisableVpcClassicLinkDnsSupport DisassociateAddress DisassociateRouteTable DisassociateSubnetCidrBlock DisassociateVpcCidrBlock EnableVgwRoutePropagation EnableVolumeIO EnableVpcClassicLinkDnsSupport GetConsoleOutput GetHostReservationPurchasePreview GetPasswordData GetReservedInstancesExchangeQuote ImportImage ImportInstance ImportKeyPair ImportSnapshot ImportVolume ModifyHosts ModifyIdentityIdFormat ModifyIdFormat ModifyImageAttribute ModifyInstanceAttribute ModifyInstancePlacement ModifyNetworkInterfaceAttribute ModifyReservedInstances ModifySnapshotAttribute ModifySpotFleetRequest ModifySubnetAttribute ModifyVolume ModifyVolumeAttribute ModifyVpcAttribute ModifyVpcEndpoint ModifyVpcPeeringConnectionOptions MonitorInstances MoveAddressToVpc PurchaseHostReservation PurchaseReservedInstancesOffering PurchaseScheduledInstances RegisterImage ReleaseAddress ReleaseHosts ReplaceNetworkAclAssociation ReplaceNetworkAclEntry ReplaceRoute ReplaceRouteTableAssociation ReportInstanceStatus RequestSpotFleet RequestSpotInstances ResetImageAttribute ResetInstanceAttribute ResetNetworkInterfaceAttribute ResetSnapshotAttribute RestoreAddressToClassic RunScheduledInstances UnassignIpv6Addresses UnassignPrivateIpAddresses UnmonitorInstances
Conclusion
This post introduced error contents and workarounds when creating IAM policies that use "Resource-based permissions".Amazon EC2 APIs that support resource level permissions and those that do not were listed.When creating IAM policies, the differences in support for "Resource-Level Permissions" should be considered.
References
Granting IAM Users Required Permissions for Amazon EC2 Resources Demystifying EC2 Resource-Level Permissions